﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Engine;
using Engine.Math;
using Microsoft.Xna.Framework;
using ThinkDotNetBotApiCommon;
using ThinkDotNetEngine.Bots;
using ThinkDotNetEngine.Bots.Loaders;

namespace ThinkDotNetEngine
{
    [Serializable]
    public class Arena:World
    {
        public Arena(Game game) : base(game)
        {
        }

        #region Properties

        public Vector3 SkyCenterTop
        {
            get
            {
                float terrainSize = Math.Max(Terrain.HeightmapWidth, Terrain.HeightmapHeight);
                return new Vector3(0, terrainSize/2f,0);
            }
        }

        [NonSerialized] 
        private List<TankBot> _bots;

        public List<TankBot> Bots
        {
            get { return _bots; }
            set { _bots = value; }
        }

        #endregion

        #region Public Methods

        public override object DetectCollision(Vector3 position)
        {
            object intersectedObject = base.DetectCollision(position);
            if(intersectedObject!=null)
                return intersectedObject;

            foreach (var tankBot in Bots)
            {
                BoundingBox transformedBoundingBox = tankBot.InitialBoundingBox.Transform(tankBot.WorldMatrix);
                if (transformedBoundingBox.Contains(position) != ContainmentType.Disjoint)
                    return tankBot;
            }
            return null;
        }
        public IEnumerable<TankBot> DetectCollisionWithOtherBotsAfterMovement(TankBot tankBot, Vector3 wantedOffset)
        {
            BoundingBox newPosBoundingBox = tankBot.InitialBoundingBox.Transform(tankBot.WorldMatrix);
            newPosBoundingBox.Min += wantedOffset;
            newPosBoundingBox.Max += wantedOffset;

            foreach (var otherBot in Bots)
            {
                if (otherBot != tankBot)
                {
                    BoundingBox transformedBoundingBox = otherBot.InitialBoundingBox.Transform(otherBot.WorldMatrix);
                    if (transformedBoundingBox.Contains(newPosBoundingBox) != ContainmentType.Disjoint)
                        yield return otherBot;
                }
            }
        }
        public IEnumerable<IScanableItem> GetBotsInRadiusArea(Vector3 center, float radius)
        {
            foreach (TankBot tankBot in Bots)
            {
                float dist = Vector3.Distance(tankBot.Translation, center);
                if (dist <= radius)
                {
                    BotInfo botInfo = new BotInfo(tankBot.InitialBoundingBox);
                    botInfo.Translation = tankBot.Translation;
                    botInfo.Id = tankBot.Id;
                    yield return botInfo;
                }
            }
        }        
        public IEnumerable<IScanableItem> GetAllObjectsInRadiusArea(Vector3 center,float radius)
        {
            List<IScanableItem> scanableItems=new List<IScanableItem>();

            foreach (var staticObject in GetStaticObjectsInRadiusArea(center,radius))
            {
                var staticObjectInfo = new StaticObjectInfo(staticObject.InitialBoundingBox, staticObject.Translation,staticObject.GetHashCode());                
                scanableItems.Add(staticObjectInfo);
            }
            scanableItems.AddRange(GetBotsInRadiusArea(center,radius));
            return scanableItems;
        }        

        #endregion

        #region Event Handlers    

        #endregion

        #region Private Methods
  
        #endregion
    }
}
